package com.jzo2o.orders.manager.service.client;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.jzo2o.api.market.CouponApi;
import com.jzo2o.api.market.dto.request.CouponUseBackReqDTO;
import com.jzo2o.api.market.dto.request.CouponUseReqDTO;
import com.jzo2o.api.market.dto.response.AvailableCouponsResDTO;
import com.jzo2o.api.market.dto.response.CouponDTO;
import com.jzo2o.api.market.dto.response.CouponUseResDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;

/**
 * @author itlxc
 * @since 2024-11-06
 */
@Component
@Slf4j
public class MarketClient {

    @Resource
    private CouponApi couponApi;

    @SentinelResource(value = "getAvailableByCouponApi", fallback = "getAvailableFallback", blockHandler = "getAvailableBlockHandler")
    public List<AvailableCouponsResDTO> getAvailable(BigDecimal totalAmount) {

        log.info("查询可用优惠券,订单金额:{}",totalAmount);
        //调用可用优惠券
        return couponApi.getAvailable(totalAmount);
    }

    @SentinelResource(value = "useAvailableByCouponApi", fallback = "getAvailableFallback", blockHandler = "getAvailableBlockHandler")
    public CouponUseResDTO use(@RequestBody CouponUseReqDTO couponUseReqDTO) {
        log.info("优惠券核销,优惠券核销参数:{}",couponUseReqDTO);
        return couponApi.use(couponUseReqDTO);
    }

    @SentinelResource(value = "useBackAvailableByCouponApi", fallback = "getAvailableFallback", blockHandler = "getAvailableBlockHandler")
    public void useBack(CouponUseBackReqDTO couponUseBackReqDTO) {
        log.info("优惠券退回,优惠券退回参数:{}",couponUseBackReqDTO);
        couponApi.useBack(couponUseBackReqDTO);
    }

    @SentinelResource(value = "getCouponByCouponApi", fallback = "getAvailableFallback", blockHandler = "getAvailableBlockHandler")
    public CouponDTO getCouponByOrderId(Long id) {
        log.info("根据优惠券id查询优惠券信息,优惠券id:{}",id);
        return couponApi.getByOrderId(id);
    }

    //执行异常走
    public List<AvailableCouponsResDTO> getAvailableFallback(BigDecimal totalAmount, Throwable throwable) {
        log.error("非限流、熔断等导致的异常执行的降级方法，totalAmount:{},throwable:", totalAmount, throwable);
        return Collections.emptyList();
    }

    //熔断后的降级逻辑
    public List<AvailableCouponsResDTO> getAvailableBlockHandler(BigDecimal totalAmount, BlockException blockException) {
        log.error("触发限流、熔断时执行的降级方法，totalAmount:{},blockException:", totalAmount, blockException);
        return Collections.emptyList();
    }
}
